package enemies;

import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.ImageIcon;

import towers.Tower;
import core.Model;
import core.ShootingUnit;
import core.Vector;

/**
 * @author onbekend
 * @version 1.1
 * @since 2011-04-11
 */
public abstract class Enemy extends ShootingUnit {

	protected Tower aimAtTower;
	protected int speed;
	protected Vector direction;
	protected int nextDestination = 0;

	protected ArrayList<Point2D.Double> route;

	/**
	 * 
	 * @param route de route
	 * @param position de positie
	 * @param health de hitpoints
	 * @param size de groote
	 * @param image het plaatje
	 * @param firerate de schietsnelheid
	 * @param range de afstand waarover geschoten kan worden
	 * @param speed de snelheid van de unit
	 */
	/* /// Constructor //////////////////////////////////////// */
	public Enemy(ArrayList<Point2D.Double> route, Point2D.Double position, int health, Dimension size, ImageIcon image,
			int firerate, int range, int speed) {
		super(position, health, image, size, 0, range, firerate);

		this.route = route;
		this.speed = speed;
	}

	/* /// getTower //////////////////////////////////////// */
	public Tower getTower() {
		return aimAtTower;
	}

	/* /// setTower //////////////////////////////////////// */
	public void setTower(Tower target) {
		aimAtTower = target;
	}

	/* /// getSpeed //////////////////////////////////////// */
	public int getSpeed() {
		return speed;
	}

	/* /// setSpeed //////////////////////////////////////// */
	public void setSpeed(int speed) {
		this.speed = speed;
	}

	/**
	 * Deze functie update de vijand
	 *
	 * @see core.ShootingUnit#update()
	 * @return true als gelukt, anders false
	 */
	/* /// update //////////////////////////////////////// */
	public boolean update() {

		// Is de tower al kapot?
		if (aimAtTower != null && aimAtTower.getHealth() <= 0)
			aimAtTower = null;

		// Enemy beweegt naar bestemming
		if (nextDestination < route.size()) {

			double deltaSpeed = this.speed * Model.timerInterval;

			// Volgende punt ophalen, wat ook bestemming is
			Point2D.Double dest = route.get(nextDestination);

			// Bereken richting
			this.direction = new Vector(dest.x - position.x, dest.y - position.y).normalize();

			// Beweeg naar bestemming
			setPosition(new Point2D.Double(this.position.x + (direction.x * deltaSpeed), this.position.y
					+ (direction.y * deltaSpeed)));

			// Viewangle aanpassen, moet wijzen naar bestemming

			double x = dest.x - position.x;
			double y = dest.y - position.y;
			// punt links van enemy
			if (x < 0) {
				// punt hoger dan enemy
				x *= -1;
				if (y < 0) {
					y *= -1;
					viewAngle = (int) Math.toDegrees((Math.atan((y / x)))) + 90;
				}
				// punt lager dan enemy
				else if (y >= 0) {
					viewAngle = (int) Math.toDegrees((Math.atan((x / y))));
				}
				// punt rechts van enemy
			} else if (x >= 0) {
				if (y < 0) {
					y *= -1;
					viewAngle = (int) Math.toDegrees((Math.atan((x / y)))) + 180;
				} else if (y >= 0) {
					viewAngle = (int) Math.toDegrees((Math.atan((y / x)))) + 270;
				}
			}

			// Papa update bounds
			super.update();

			// Zijn we aangekomen op de bestemming? Naar de volgende!
			// Kijk of we erg dichtbij zijn aangezien het niet altijd zeker is
			// dat de vijand precies de bestemming bereikt
			if (Math.abs(dest.x - position.x) < 5 && Math.abs(dest.y - position.y) < 5)
				nextDestination++;

			return true;
		}
		return false;
	}

	/**
	 * Geeft een Tower-object terug waarop de enemy richt
	 * 
	 * @return Tower
	 */
	/* /// getAimAtTower //////////////////////////////////////// */
	public Tower getAimAtTower() {
		return aimAtTower;
	}

	/* /// getDirection //////////////////////////////////////// */
	public Vector getDirection() {
		return direction;
	}

}
